using System;
using NUnit.Framework;
using Pyxis.FluentSelenium.Conditions;
using Pyxis.FluentSelenium.Locator;
using Pyxis.FluentSelenium.Tester;
using Selenium;

namespace Pyxis.FluentSelenium.SampleWebAppTest.Shopper
{
    static class ContentTesterExtension
    {
        public static void ShouldContainANumber(this ContentTester contentTester)
        {
            var acctualText = contentTester.Selenium.GetText(contentTester.Locator.ToString());
            int temporaryResult;
            var isNumber = Int32.TryParse(acctualText.Trim(), out temporaryResult);
            Assert.IsTrue(isNumber);
        }
    }

    public class AnyNumberValidator : IContentValidator
    {
        public void Validate(ContentTester contentTester)
        {
            var acctualText = contentTester.Selenium.GetText(contentTester.Locator.ToString());
            int temporaryResult;
            var isNumber = Int32.TryParse(acctualText.Trim(), out temporaryResult);
            Assert.IsTrue(isNumber);
        }
    }

    static class ShoppingOnlinePage
    {
        public static PageLoadWaitCondition PageLoadWaitCondition = new PageLoadWaitCondition("Shopping/ShopOnline.aspx");
        public static ElementLocator UnitePriceField = ElementLocator.WithId("unitPrice");
        public static ButtonLocator ProceedToCheckoutButton = ButtonLocator.WithId("proceeedToCheckout");
        public static InputLocator NumberOfItemsField = InputLocator.WithId("numberOfUnits");
    }

    static class ConfirmOrderPage
    {
        public static PageLoadWaitCondition PageLoadWaitCondition = new PageLoadWaitCondition("Shopping/OrderSubmited.aspx");

        public static ElementLocator TotalAmmountOfPurchaseBox = ElementLocator.WithId("totalPrice");
        public static ButtonLocator SubmitOrderButton = ButtonLocator.WithId("submitOrder");
        public static ComboboxLocator SelectShippingMethod = ComboboxLocator.WithId("shippingMethod");
    }

    static class OrderSubmitedPage
    {
        public static PageLoadWaitCondition PageLoadWaitCondition = new PageLoadWaitCondition("Shopping/OrderSubmited.aspx");
        public static ElementLocator OrderNumber = ElementLocator.WithId("orderNumber");
        public static ElementLocator ShippingMethod = ElementLocator.WithId("shippingMethod");

    }

    [TestFixture]
    public class ShopperPurchaseTest
    {
        private PageLoadWaitCondition ShoppingOnlinePageLoadWait = PageLoadWaitCondition.For("Shopping/ShopOnline.aspx");
        private readonly PageLoadWaitCondition OrderSubmitedPageLoadWait = PageLoadWaitCondition.For("Shopping/OrderSubmited.aspx");
        private readonly PageLoadWaitCondition ConfirmOrderPageLoadWait = PageLoadWaitCondition.For("Shopping/ConfirmOrder.aspx");

        private readonly ElementLocator UnitePriceField = ElementLocator.WithId("unitPrice");
        private readonly ButtonLocator ProceedToCheckoutButton = ButtonLocator.WithId("proceeedToCheckout");
        private readonly InputLocator NumberOfItemsField = InputLocator.WithId("numberOfUnits");
        private readonly ElementLocator TotalAmmountOfPurchaseBox = ElementLocator.WithId("totalPrice");
        private readonly ButtonLocator SubmitOrderButton = ButtonLocator.WithId("submitOrder");
        private readonly ComboboxLocator SelectShippingMethod = ComboboxLocator.WithId("shippingMethod");
        private readonly ElementLocator OrderNumber = ElementLocator.WithId("orderNumber");
        private readonly ElementLocator ShippingMethod = ElementLocator.WithId("shippingMethod");

        private readonly AnyNumberValidator AnyNumber = new AnyNumberValidator();

        private WebApplication shopOnline;
        private User shopper;

        
        [Test]
        public void TestSuccefullySubmitingShoppingOrder()
        {
            shopper.Goto("Shopping/ShopOnline.aspx");

            shopper.For(UnitePriceField).ShouldSee("5,00$");
            shopper.For(NumberOfItemsField).Enters("2");
            shopper.For(ProceedToCheckoutButton).Clicks();

            shopper.WaitFor(ConfirmOrderPageLoadWait);
            shopper.For(TotalAmmountOfPurchaseBox).ShouldSee("10,00$");
            shopper.For(SelectShippingMethod).Selects("snail mail");
            shopper.For(SubmitOrderButton).Clicks();

            shopper.WaitFor(OrderSubmitedPageLoadWait);
            shopper.For(OrderNumber).ShouldContainANumber();
            shopper.For(OrderNumber).ShouldSee(AnyNumber);
            shopper.For(ShippingMethod).ShouldSee("snail mail");
        }


        [Test]
        public void TestSuccefullySubmitingShoppingOrder_Alternate()
        {
            shopper.Goto("Shopping/ShopOnline.aspx");

            shopper.For(ShoppingOnlinePage.UnitePriceField).ShouldSee("5,00$");
            shopper.For(ShoppingOnlinePage.NumberOfItemsField).Enters("2");
            shopper.For(ShoppingOnlinePage.ProceedToCheckoutButton).Clicks();

            shopper.WaitFor(ConfirmOrderPage.PageLoadWaitCondition);
            shopper.For(ConfirmOrderPage.TotalAmmountOfPurchaseBox).ShouldSee("10,00$");
            shopper.For(ConfirmOrderPage.SelectShippingMethod).Selects("snail mail");
            shopper.For(ConfirmOrderPage.SubmitOrderButton).Clicks();

            shopper.WaitFor(OrderSubmitedPage.PageLoadWaitCondition);
            shopper.For(OrderSubmitedPage.OrderNumber).ShouldContainANumber();
            shopper.For(OrderSubmitedPage.OrderNumber).ShouldSee(AnyNumber);
            shopper.For(OrderSubmitedPage.ShippingMethod).ShouldSee("snail mail");
        }

        private readonly ElementLocator FeaturedProductArea = ElementLocator.WithId("featuredProduct");
        private readonly ElementLocator WelcomeMessageBox = ElementLocator.WithId("welcome");


        private readonly ElementLocator FeaturedProductTitle = ElementLocator.WithXpath("//*[@id='featuredProduct']//*[@id='title']");
        private readonly ElementLocator FeaturedProductUnitePriceField = ElementLocator.WithXpath("//*[@id='featuredProduct']//*[@id='price']");

        [Test]
        public void TestWelcomeScreenShowsPromotedProducts()
        {
            shopper.Goto("Shopping/ShopOnline.aspx");
            shopper.For(WelcomeMessageBox).ShouldSee("Welcome to Shop-e online!");
            shopper.ShouldSee(FeaturedProductArea);
            shopper.For(FeaturedProductTitle).ShouldSee("blank CDs (10)");
            shopper.For(FeaturedProductUnitePriceField).ShouldSee("5,00$");
        }

        [SetUp]
        public void Initialise()
        {
            shopOnline = new WebApplication(3000, "Pyxis.FluentSelenium.SampleWebApp");
            shopOnline.Start();

            var selenium = new DefaultSelenium("127.0.0.1", 4445, "*iexplore", "http://localhost:3000/");
            shopper = new User(selenium);
            shopper.Start();
        }

        [TearDown]
        public void Cleanup()
        {
            shopper.Stop();
            shopOnline.Stop();
        }

    }
}